from django.template import Library
from django.shortcuts import get_object_or_404
from datetime import date
from datetime import timedelta
from projects.models import Deliverable,Person
from projects import utils

register = Library()

@register.inclusion_tag("objective_table.html")
def list_objectives(person):
  set = person.objective_set.all()
  return {'objective_list': set}

@register.inclusion_tag("objective_detail.html")
def detail_objectives(person):
  set = person.objective_set.all()
  return {'objective_list': set}

@register.inclusion_tag("task_table.html")
def list_tasks(person):
  set = person.task_set.all()
  return {'task_list': set}

@register.inclusion_tag("task_table.html")
def list_todays_tasks(person):
  return {'task_list': person.task_set.dueToday()}
  
@register.inclusion_tag("task_detail.html")
def detail_todays_tasks(person):
  return {'task_list': person.task_set.dueToday()}

@register.inclusion_tag("task_table.html")
def list_overdue_tasks(person):
  return {'task_list': person.task_set.overdue().order_by('target_date', 'start_date')}
  
@register.inclusion_tag("task_detail.html")
def detail_overdue_tasks(person):
  return {'task_list': person.task_set.overdue().order_by('target_date', 'start_date')}
  
@register.inclusion_tag("task_table.html")
def list_incomplete_tasks(person):
  set = person.task_set.filter(completed_date = None).order_by('target_date', 'start_date')
  return {'task_list': set}

@register.inclusion_tag("task_detail.html")
def detail_incomplete_tasks(person):
  set = person.task_set.filter(completed_date = None).order_by('target_date', 'start_date')
  return {'task_list': set}

@register.inclusion_tag("deliverable_table.html")
def list_deliverables(person):
  set = person.deliverable_set.all()
  return {'deliverable_list': set}

@register.inclusion_tag("deliverable_table.html")
def list_incomplete_deliverables(person):
  set = person.deliverable_set.filter(completed_date = None).order_by('target_date', 'start_date')
  return {'deliverable_list': set}

@register.inclusion_tag("deliverable_detail.html")
def detail_incomplete_deliverables(person):
  set = person.deliverable_set.filter(completed_date = None).order_by('target_date', 'start_date')
  return {'deliverable_list': set}

@register.inclusion_tag("rating.html")
def person_status(person):
  if not isinstance(person, Person):
    person = get_object_or_404(Person, id=person.id)
  incomplete_tasks = person.task_set.filter(completed_date = None)
  incomplete_deliverables = person.deliverable_set.filter(completed_date = None)
  objectives = person.objective_set.all()
  return utils.get_ratings("person", incomplete_tasks, incomplete_deliverables, objectives)

@register.inclusion_tag("allocation.html")
def person_allocation(person, duration):
  """
  Creates a snippet of HTML that describes the time allocation status of this
  individual over a given period of days. The calculations take into account the
  amount of effort provides and assumes that a deliverable for which the 
  individual is lead is entirely the responsibility of the lead unless a task is
  defined and assigned to another person. In this later case the time estimated
  for the task will be deducted from the deliverable estimate.
  """
  if not isinstance(person, Person):
    person = get_object_or_404(Person, id=person.id)
  error = None
  allocated_time = 0
  estimated = 0
  no_estimate = 0
  
  td = timedelta(days=duration)
  end_date = date.today() + td
  
  incomplete_deliverables = person.deliverable_set.filter(completed_date = None).filter(start_date__lte = date.today()).filter(target_date__lte = end_date)
  for deliverable in incomplete_deliverables:
      if deliverable.estimate != None:
        allocated_time = allocated_time + deliverable.estimate
        estimated = estimated + 1
      else:
        no_estimate = no_estimate + 1
      incomplete_tasks = deliverable.task.filter(completed_date = None).filter(start_date__lte = date.today()).filter(target_date__lte = end_date)
      for task in incomplete_tasks:
          print(task)
          if task.estimate != None and task.lead != person.id:
             print ("removing time")
             allocated_time = allocated_time - task.estimate
          elif task.estimate == None and task.lead == person.id:
             no_estimate = no_estimate + 1 
        
  incomplete_tasks = person.task_set.filter(completed_date = None).filter(start_date__lte = date.today()).filter(target_date__lte = end_date)
  for t in incomplete_tasks:
      if t.estimate != None:
        deliverables = Deliverable.objects.filter(task = t.id)
        if t.parent != None:
            allocated_time = allocated_time + t.estimate
            estimated = estimated + 1
        for deliverable in deliverables:
            if deliverable.owner.id != person.id:
                ''' only add the time if this person is not deliverable lead as well as the time will be included in the deliverable estimate '''
                allocated_time = allocated_time + t.estimate
                estimated = estimated + 1
      else:
        no_estimate = no_estimate + 1
  
  if (person.effort == 0):
      available_time = 0
  else:
      available_time =  int(((duration / 7) * (5 * person.effort)) * (float(5 * 60)))
      
  if no_estimate == 0:
    no_estimate = None
  
  if available_time < allocated_time:
    error = "This person is over-allocated"
  
  return {"person_id": person.id,
          "warning": error, 
          "available_time": available_time, 
          "allocated_time": allocated_time, 
          "estimated": estimated, 
          "no_estimate": no_estimate}
